Add resource command arguments and visibility#16710
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16710Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 16710" |
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for resource command argument metadata and command visibility across Aspire Hosting, Dashboard, CLI, auxiliary backchannel, and polyglot SDK generation, including validation flows that return structured field errors without executing the command.
Changes:
- Flow command argument definitions (
InteractionInput) through snapshots/service contracts/JSON and addInteractionInputCollectionaccessors for typed reads. - Add command visibility metadata and enforce it in Dashboard (Dashboard-only) and CLI/API discovery (API-visible).
- Extend Dashboard/CLI/MCP/backchannel execution paths to submit arguments and receive structured validation errors; update polyglot codegen accordingly.
Show a summary per file
| File | Description |
|---|---|
| tests/Shared/TestDashboardClient.cs | Updates test dashboard client API to include arguments/validate-only parameters. |
| tests/PolyglotAppHosts/Aspire.Hosting/TypeScript/apphost.ts | Updates TypeScript apphost usage for getter-only promise APIs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Foundry/TypeScript/apphost.ts | Updates Foundry TypeScript apphost for getter-only promise APIs. |
| tests/PolyglotAppHosts/Aspire.Hosting.Foundry/Java/AppHost.java | Updates Foundry Java apphost config mutation patterns. |
| tests/Aspire.Hosting.Tests/ResourceCommandServiceTests.cs | Adds unit tests for argument mapping/validation behavior in Hosting. |
| tests/Aspire.Hosting.Tests/Dashboard/DashboardServiceTests.cs | Adds dashboard service tests for argument metadata, visibility, and validate-only execution. |
| tests/Aspire.Hosting.Tests/Backchannel/AuxiliaryBackchannelTests.cs | Updates capability test naming to reflect current capability set. |
| tests/Aspire.Hosting.Tests/Backchannel/AuxiliaryBackchannelRpcTargetTests.cs | Adds backchannel tests for JSON argument mapping and validate-only validation errors. |
| tests/Aspire.Hosting.RemoteHost.Tests/AtsCapabilityScannerTests.cs | Updates ATS scanner test expectations for deprecated command option surface. |
| tests/Aspire.Hosting.EntityFrameworkCore.Tests/EFCoreOperationExecutorTests.cs | Updates EFCore tool command creation for new command constructor parameters. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/transport.verified.ts | Updates TS transport snapshot (including callback marshalling). |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/base.verified.ts | Adds TS InteractionInputCollection wrapper and InputType enum snapshot. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/Snapshots/AtsGeneratedAspire.verified.ts | Exports InteractionInputCollection/InputType from generated SDK snapshot. |
| tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs | Adds assertions for generated arguments() API surface. |
| tests/Aspire.Hosting.CodeGeneration.Rust.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.rs | Updates Rust snapshot for new enums/DTOs and command validation context exposure. |
| tests/Aspire.Hosting.CodeGeneration.Python.Tests/Snapshots/TwoPassScanningGeneratedAspire.verified.py | Updates Python snapshot for new literals/types and removed init-only setters. |
| tests/Aspire.Dashboard.Tests/ResourceOutgoingPeerResolverTests.cs | Updates dashboard test mock to new ExecuteResourceCommandAsync signature. |
| tests/Aspire.Dashboard.Tests/Model/DashboardCommandExecutorTests.cs | Adds tests for dashboard-side argument marshalling behavior. |
| tests/Aspire.Dashboard.Tests/Integration/Playwright/Infrastructure/MockDashboardClient.cs | Updates Playwright dashboard mock for new command execution signature. |
| tests/Aspire.Dashboard.Components.Tests/Pages/ConsoleLogsTests.cs | Updates command view model construction to use argument inputs. |
| tests/Aspire.Dashboard.Components.Tests/Controls/ResourceDetailsTests.cs | Updates command view model construction to use argument inputs. |
| tests/Aspire.Cli.Tests/TestServices/TestAppHostAuxiliaryBackchannel.cs | Captures backchannel command arguments and call counts for tests. |
| tests/Aspire.Cli.Tests/Mcp/ExecuteResourceCommandToolTests.cs | Adds MCP tool tests for argument forwarding and validation error formatting. |
| tests/Aspire.Cli.Tests/Mcp/ApiDocs/ApiDocsIndexServiceTests.cs | Makes test fetcher request tracking thread-safe under concurrency. |
| tests/Aspire.Cli.Tests/Commands/ResourceCommandTests.cs | Adds CLI tests for forwarding loose/ordered command arguments to backchannel. |
| tests/Aspire.Cli.Tests/Commands/ResourceCommandHelperTests.cs | Adds CLI helper tests for argument forwarding and validation error display. |
| tests/Aspire.Cli.Tests/Backchannel/ResourceSnapshotMapperTests.cs | Extends CLI snapshot mapping tests for visibility and argument input metadata. |
| tests/Aspire.Cli.EndToEnd.Tests/TypeScriptReusablePackageTests.cs | Updates E2E TS snippets for getter-only promise APIs. |
| src/Shared/Model/Serialization/ResourceJson.cs | Extends shared resource JSON schema with command visibility and argument inputs. |
| src/Aspire.TypeSystem/AtsCapabilityInfo.cs | Adds callback metadata (signature) to DTO property info. |
| src/Aspire.Hosting/ResourceBuilderExtensions.cs | Validates command argument metadata and wires new command annotation constructor. |
| src/Aspire.Hosting/Orchestrator/ParameterProcessor.cs | Updates parameter commands to new command constructor signature. |
| src/Aspire.Hosting/IInteractionService.cs | Exposes InteractionInput/InteractionInputCollection to ATS and adds typed accessors + ToArray export. |
| src/Aspire.Hosting/Dashboard/proto/Partials.cs | Filters commands by dashboard visibility and adds argument input DTO mapping. |
| src/Aspire.Hosting/Dashboard/proto/dashboard_service.proto | Extends gRPC contract with argument inputs/arguments payload and validation-only semantics; deprecates parameter. |
| src/Aspire.Hosting/Dashboard/DashboardServiceData.cs | Adds argument creation and validate-only execution path with invalid-argument reporting. |
| src/Aspire.Hosting/Dashboard/DashboardService.cs | Implements argument conversion/validation-only execution and returns structured invalid arguments. |
| src/Aspire.Hosting/Backchannel/BackchannelDataTypes.cs | Extends auxiliary backchannel request/response and snapshots for args/visibility/validation errors. |
| src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs | Adds JSON object/array argument mapping, validate-only path, and snapshot argument metadata/visibility. |
| src/Aspire.Hosting/ApplicationModel/ResourceNotificationService.cs | Flows argument metadata and visibility into resource command snapshots. |
| src/Aspire.Hosting/ApplicationModel/ResourceCommandService.cs | Adds argument mapping (named+ordered), built-in validation + custom validation callback, and surfaces invalid args. |
| src/Aspire.Hosting/ApplicationModel/ResourceCommandAnnotation.cs | Adds arguments/visibility/validation callback to command annotation and adds ExecuteCommandContext.Arguments. |
| src/Aspire.Hosting/ApplicationModel/CustomResourceSnapshot.cs | Extends ResourceCommandSnapshot with arguments and visibility metadata. |
| src/Aspire.Hosting/ApplicationModel/CommandsConfigurationExtensions.cs | Updates lifecycle commands to new command constructor signature. |
| src/Aspire.Hosting/ApplicationModel/CommandOptions.cs | Adds command arguments/visibility/validation callback surface; deprecates Parameter. |
| src/Aspire.Hosting.RemoteHost/AtsCapabilityScanner.cs | Enhances ATS scanning for callbacks and suppresses init-only setters from generated capabilities. |
| src/Aspire.Hosting.RemoteHost/Ats/AtsMarshaller.cs | Supports DTO deserialization that includes delegate callback properties. |
| src/Aspire.Hosting.Integration.Analyzers/AspireExportAnalyzer.cs | Avoids generating setters for init-only properties in analyzer. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/transport.ts | Marshals functions as callbacks in TS transport layer. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/Resources/base.ts | Adds TS InputType + InteractionInputCollection wrapper utilities. |
| src/Aspire.Hosting.CodeGeneration.TypeScript/AtsTypeScriptCodeGenerator.cs | Emits TS callback property types, promise-wrapper chaining for getter-only APIs, and special-cases interaction input types. |
| src/Aspire.Dashboard/ServiceClient/Partials.cs | Maps gRPC command argument inputs and response invalid inputs into view models. |
| src/Aspire.Dashboard/ServiceClient/IDashboardClient.cs | Extends dashboard client interface for arguments and validate-only support. |
| src/Aspire.Dashboard/ServiceClient/DashboardClient.cs | Sends arguments/validate-only flags in ExecuteResourceCommand requests. |
| src/Aspire.Dashboard/Model/ResourceViewModel.cs | Updates command view model to carry argument input metadata instead of legacy parameter. |
| src/Aspire.Dashboard/Model/ResourceCommandResponseViewModel.cs | Adds validation-failed kind and carries invalid argument inputs for UI display. |
| src/Aspire.Dashboard/Model/DashboardCommandExecutor.cs | Adds UI flow to collect arguments, validate-only roundtrip, and execute with submitted args. |
| src/Aspire.Cli/Mcp/Tools/ListResourcesTool.cs | Extends MCP JSON serialization context for command argument metadata. |
| src/Aspire.Cli/Mcp/Tools/ExecuteResourceCommandTool.cs | Adds MCP command argument forwarding and formats structured validation errors. |
| src/Aspire.Cli/JsonSourceGenerationContext.cs | Adds source-gen support for serializing string arrays (ordered args). |
| src/Aspire.Cli/Commands/ResourceCommandHelper.cs | Adds optional JSON arguments parameter and appends validation errors to error output. |
| src/Aspire.Cli/Commands/ResourceCommand.cs | Captures unmatched tokens as ordered arguments and forwards them to backchannel execution. |
| src/Aspire.Cli/Commands/PsCommand.cs | Extends PS command JSON serialization context for argument metadata. |
| src/Aspire.Cli/Commands/DescribeCommand.cs | Extends describe output JSON serialization context for argument metadata. |
| src/Aspire.Cli/Backchannel/ResourceSnapshotMapper.cs | Filters commands by API visibility and maps argument inputs/visibility into JSON output. |
| src/Aspire.Cli/Backchannel/IAppHostAuxiliaryBackchannel.cs | Extends backchannel interface to accept optional command arguments payload. |
| src/Aspire.Cli/Backchannel/BackchannelJsonSerializerContext.cs | Adds source-gen support for new backchannel types (args + validation errors). |
| src/Aspire.Cli/Backchannel/AppHostAuxiliaryBackchannel.cs | Sends command arguments over auxiliary backchannel RPC. |
| playground/TypeScriptAppHost/apphost.ts | Adds sample TS command with arguments + validation callback demonstrating the API. |
| playground/Stress/Stress.AppHost/AppHost.cs | Adds stress playground commands that exercise argument metadata, visibility, validation, and ordered CLI args. |
Copilot's findings
- Files reviewed: 73/73 changed files
- Comments generated: 2
mitchdenny
left a comment
There was a problem hiding this comment.
5 non-blocking comments on the new resource command arguments / validate-only / visibility surface — all distinct from the existing review threads. Mostly correctness/UX edge cases (validate-only Success masking not-found, Trim() on SecretText, Number input silent-fallback in dashboard, Options ToDictionary on duplicate keys, GetInt32 vs Number-as-double).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Allow resource command invocations to capture trailing arguments and map them through discovered command argument inputs. Keep --args-json as a hidden legacy alias for the new --arguments option. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the resource command JSON arguments option and rely on the variadic command arguments captured by System.CommandLine. A single trailing JSON object remains supported as the structured escape hatch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expose typed command argument validation callbacks to polyglot AppHosts, add the TypeScript interaction input intrinsic, and keep CLI invocation positional. Also validates the TypeScript playground command path and fixes Dashboard argument dialog closing after successful validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the generated callable getter for ExecuteCommandContext.resourceName so the helper package sample matches the current TypeScript SDK shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Forward validateOnly through the TestDashboardClient command delegate and update stale auxiliary backchannel capability comments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8d54b4b to
a79e590
Compare
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
IEvangelist
left a comment
There was a problem hiding this comment.
Two findings — both are issues that complement the existing review threads rather than duplicating them.
Bugs / correctness
- 1 issue: misaligned [Experimental] attribute on the legacy ResourceCommandAnnotation constructor (source-breaking for previously-stable API)
API / UX consistency
- 1 issue: asymmetric handling of unknown argument names between the dictionary (Dashboard/MCP) and ordered (CLI) CreateCommandArguments overloads
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
joperezr
left a comment
There was a problem hiding this comment.
A few things I noticed while looking through this. Mostly small reuse / consistency stuff plus one I think is worth a look.
joperezr
left a comment
There was a problem hiding this comment.
A few more, all consider/follow-up rather than blockers.
|
One more thing, not for this PR — once this lands, it'd be nice to update the
Happy to file a follow-up issue / PR for the skill update if you agree it's worth doing — no need to block this on it. |
|
🎬 CLI E2E Test Recordings — 77 recordings uploaded (commit View all recordings
📹 Recordings uploaded automatically from CI run #25577861108 |
…ource-commands Documents new features from microsoft/aspire#16710: - Command arguments (InteractionInput, InputType, InteractionInputCollection) - Typed argument accessors (GetString, GetBoolean, GetInt32, GetDouble in C#; toArray, value, requiredValue in TypeScript) - Positional CLI argument passing - Argument validation (ValidateArguments callback, field-level errors) - Command visibility (ResourceCommandVisibility.Dashboard, Api, All) Covers both C# and TypeScript AppHost usage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Pull request created: #892
|
|
📝 Documentation has been drafted in microsoft/aspire.dev#892 targeting Updated
Targeting Note This draft PR needs human review before merging. |
…ource-commands Documents new features from microsoft/aspire#16710: - Command arguments (InteractionInput, InputType, InteractionInputCollection) - Typed argument accessors (GetString, GetBoolean, GetInt32, GetDouble in C#; toArray, value, requiredValue in TypeScript) - Positional CLI argument passing - Argument validation (ValidateArguments callback, field-level errors) - Command visibility (ResourceCommandVisibility.Dashboard, Api, All) Covers both C# and TypeScript AppHost usage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…source-commands (#892) * docs: add command arguments, validation, and visibility to custom-resource-commands Documents new features from microsoft/aspire#16710: - Command arguments (InteractionInput, InputType, InteractionInputCollection) - Typed argument accessors (GetString, GetBoolean, GetInt32, GetDouble in C#; toArray, value, requiredValue in TypeScript) - Positional CLI argument passing - Argument validation (ValidateArguments callback, field-level errors) - Command visibility (ResourceCommandVisibility.Dashboard, Api, All) Covers both C# and TypeScript AppHost usage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: fix ResourceCommandVisibility names and accessor return types Verified against microsoft/aspire source: - ResourceCommandVisibility values are None, UI, Api (bit-combinable); the previously documented names Dashboard and All do not exist. Use UI | Api for "both" (the default). - InteractionInputCollection.GetInt32/GetBoolean/GetDouble return non-nullable values and throw on absent or unparseable input; only GetString returns string?. Updated comments and prose. - Replaced "GetInt32(...) ?? 1" in the example, which would not compile against a non-nullable int return, with int.TryParse against GetString. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: clarify custom command input property types Update the InteractionInput property table to reflect that Label is optional and that Choice options use the IReadOnlyList/InteractionInputOption shape from the product APIs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: aspire-repo-bot[bot] <268009190+aspire-repo-bot[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: David Fowler <davidfowl@gmail.com>
Description
Adds resource command argument metadata and command visibility support across hosting, dashboard, CLI, MCP, and polyglot code generation.
This change:
InteractionInputmetadata through resource snapshots, dashboard service contracts, JSON resource output, and the auxiliary backchannelInteractionInputCollection, matching the interaction service result modelInteractionInputCollectionfor common command argument reads (GetString,GetBoolean,GetInt32,GetDouble) and a TypeScript intrinsic with idiomatic helpers (toArray,get,required,value,requiredValue)CommandOptions.Argumentsby order and performs validation centrallyResourceCommandAnnotationconstructor for compatibilityAPI sample from the Stress playground common command:
Custom command argument validation uses the same pattern as interaction input validation. Built-in validation runs first (required, max length, choice membership, boolean, and number parsing). Interactive Dashboard execution prompts through the AppHost interaction service, so validation keeps the input dialog open with field errors. CLI/MCP execute non-interactively and receive structured argument errors:
TypeScript AppHosts get the same command argument API with idiomatic JavaScript conversion instead of C#-style
GetInt32helpers.ExecuteCommandContext.argumentsandInputsDialogValidationContext.inputsare generated as async getter methods, soawait context.arguments()returns command arguments andawait context.inputs()returns validation inputs:The TypeScript
InteractionInputCollectionwrapper caches the backing input array and exposes:Getter-only fluent APIs can now be chained naturally in TypeScript. The generated promise wrapper remains awaitable, so both styles work:
CLI resource command arguments are passed as ordered values, not matched by input name. For example, the
echo-argumentssample can be invoked as:aspire resource stress-apiservice echo-arguments "Hello E2E" 2 true chocolate sauce --apphost playground/Stress/Stress.AppHost/Stress.AppHost.csprojThe CLI captures loose/overflow tokens in order and sends them as a JSON array over the auxiliary backchannel. CLI/MCP execute non-interactively so missing or invalid arguments fail fast with structured errors. Dashboard command execution leaves argument prompting to the AppHost interaction service, which renders the standard inputs dialog in the Dashboard and supports server-side validation/dynamic updates.
The Stress playground also includes:
echo-command-arguments: small API-only primitive argument command usingResourceCommandVisibility.Apivalidate-arguments: validation/failure command using required inputs, defaults, choices, custom argument validation, and structured JSON failuresargument-stress-test: minor dashboard/API stress command with 23 argument inputs to exercise metadata, rendering, submission, and payload handlingFixes # (issue)
Checklist
<remarks />and<code />elements on your triple slash comments?aspire.devissue: